# C/C++ GPIO开发 ***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.*** --- # lgpio简介 **lgpio** 是一个用于Linux系统的GPIO控制库,提供了简单易用的C语言API来操作GPIO、I2C、SPI等外设。 ## 主要特点 - **高性能**:C语言实现,执行效率高 - **跨平台兼容**:支持多种Linux单板计算机 - **功能丰富**:支持GPIO、I2C、SPI、PWM等多种外设 - **易于集成**:提供标准的C库接口 ## 支持的功能 | **功能** | **说明** | | --- | --- | | GPIO | 通用输入输出控制 | | I2C | I²C总线通信 | | SPI | SPI总线通信 | | PWM | 脉宽调制输出 | | 通知 | GPIO中断和事件通知 | # 安装lgpio ## 从源码安装 ```bash # 安装依赖工具apt update apt install -y git build-essential # 克隆lgpio源码git clone https://github.com/joan2937/lg.git cd lg # 编译并安装makemake install# 更新动态链接库缓存 ldconfig ``` ## 验证安装 安装完成后,可以通过以下命令验证: ```bash # 检查动态库 ldconfig -p | grep lgpio ``` 应该能看到类似 *liblgpio.so* 的输出。 **其他验证方法:** ```bash # 检查库文件是否存在ls -l /usr/local/lib/liblgpio.* # 检查头文件是否存在ls -l /usr/local/include/lgpio.h ``` # GPIO控制 ## 硬件准备 - 主板 - 杜邦线 - 万用表(可选,用于测量电压) ## GPIO输出控制 以下示例演示如何使用lgpio控制GPIO引脚输出高低电平。 ### 示例代码 创建 *gpio_output.c* 文件: ```c #include #include #include #include int main(int argc, char **argv){if (argc < 3) {printf("Usage: %s \n", argv[0]);printf("Example: %s 36 1 # Set GPIO36 to HIGH\n", argv[0]);return 1;}int gpio_num = atoi(argv[1]);int pin_level = atoi(argv[2]);int h;// 打开GPIO芯片4 h = lgGpiochipOpen(4);if (h < 0) {printf("ERROR: %s (%d)\n", lguErrorText(h), h);return 1;}// 设置GPIO为输出模式并设置初始电平int e = lgGpioClaimOutput(h, 0, gpio_num, pin_level);if (e < 0) {printf("ERROR: %s (%d)\n", lguErrorText(e), e);lgGpiochipClose(h);return 1;}printf("GPIO %d set to %s\n", gpio_num, pin_level ? "HIGH (3.3V)" : "LOW (0V)");// 保持状态5秒sleep(5);// 释放GPIO资源lgGpioFree(h, gpio_num);lgGpiochipClose(h);return 0;} ``` ### 编译程序 ```bash gcc -o gpio_output gpio_output.c -llgpio ``` ### 运行测试 **测试低电平:** ```bash sudo ./gpio_output 36 0 ``` 输出:*GPIO 36 set to LOW (0V)* **测试高电平:** ```bash sudo ./gpio_output 36 1 ``` 输出:*GPIO 36 set to HIGH (3.3V)* > **提示**:GPIO36对应40Pin的Pin3。 ## GPIO输入读取 以下示例演示如何读取GPIO引脚的状态。 ### 示例代码 创建 *gpio_input.c* 文件: ```c #include #include #include #include int main(int argc, char **argv){if (argc < 2) {printf("Usage: %s \n", argv[0]);printf("Example: %s 36 # Read GPIO36 state\n", argv[0]);return 1;}int gpio_num = atoi(argv[1]);int h, e, value;// 打开GPIO芯片4 h = lgGpiochipOpen(4);if (h < 0) {printf("ERROR: %s (%d)\n", lguErrorText(h), h);return 1;}// 设置GPIO为输入模式 e = lgGpioClaimInput(h, 0, gpio_num);if (e < 0) {printf("ERROR: %s (%d)\n", lguErrorText(e), e);lgGpiochipClose(h);return 1;}printf("Reading GPIO %d state (press Ctrl+C to exit)...\n", gpio_num);// 循环读取GPIO状态while (1) { value = lgGpioRead(h, gpio_num);if (value < 0) {printf("ERROR: %s (%d)\n", lguErrorText(value), value);break;}printf("GPIO %d: %s\n", gpio_num, value ? "HIGH" : "LOW");sleep(1);}// 释放资源lgGpioFree(h, gpio_num);lgGpiochipClose(h);return 0;} ``` ### 编译和运行 ```bash # 编译 gcc -o gpio_input gpio_input.c -llgpio # 运行sudo ./gpio_input 36 ``` ## GPIO输出反馈测试 以下示例演示如何通过一个引脚输出,另一个引脚读取来验证功能。 ### 示例代码 创建 *gpio_feedback.c* 文件: ```c #include #include #include int main(){int h;int gpio_out = 36; // Pin3 - GPIO36int gpio_in = 37; // Pin5 - GPIO37// 打开GPIO芯片4 h = lgGpiochipOpen(4);if (h < 0) {printf("ERROR: %s (%d)\n", lguErrorText(h), h);return 1;}// 设置GPIO36为输出,GPIO37为输入int e1 = lgGpioClaimOutput(h, 0, gpio_out, 0);int e2 = lgGpioClaimInput(h, 0, gpio_in);if (e1 < 0 || e2 < 0) {printf("ERROR: Failed to claim GPIO\n");lgGpiochipClose(h);return 1;}printf("=== GPIO Feedback Test ===\n");printf("Output: GPIO%d (Pin3)\n", gpio_out);printf("Input: GPIO%d (Pin5)\n", gpio_in);printf("Please connect Pin3 and Pin5 together\n\n");for (int i = 0; i < 5; i++) {// 设置高电平lgGpioWrite(h, gpio_out, 1);usleep(100000); // 100msint val_high = lgGpioRead(h, gpio_in);printf("Output: HIGH | Input: %s\n", val_high ? "HIGH" : "LOW");sleep(1);// 设置低电平lgGpioWrite(h, gpio_out, 0);usleep(100000);int val_low = lgGpioRead(h, gpio_in);printf("Output: LOW | Input: %s\n", val_low ? "HIGH" : "LOW");sleep(1);}// 释放资源lgGpioFree(h, gpio_out);lgGpioFree(h, gpio_in);lgGpiochipClose(h);printf("\nTest completed\n");return 0;} ``` ### 编译和运行 ```bash # 编译 gcc -o gpio_feedback gpio_feedback.c -llgpio # 运行(需要先将Pin3和Pin5短接)sudo ./gpio_feedback ``` **预期输出:** ```plaintext === GPIO Feedback Test === Output: GPIO36 (Pin3) Input: GPIO37 (Pin5) Please connect Pin3 and Pin5 together Output: HIGH | Input: HIGH Output: LOW | Input: LOW Output: HIGH | Input: HIGH Output: LOW | Input: LOW ... ``` # GPIO引脚映射 Quectel Pi H1主要使用 */dev/gpiochip4* 进行GPIO控制。 ## 常用引脚映射 | **物理引脚** | **引脚名称** | **GPIO编号** | **GPIO芯片** | **默认功能** | | --- | --- | --- | --- | --- | | Pin3 | NFC_I2C_SDA | 36 | /dev/gpiochip4 | I2C09_SDA | | Pin5 | NFC_I2C_SCL | 37 | /dev/gpiochip4 | I2C09_SCL | | Pin7 | CAM2_RST | 77 | /dev/gpiochip4 | GPIO | | Pin11 | GPIO_16 | 16 | /dev/gpiochip4 | GPIO/SPI/UART/I2C | | Pin13 | GPIO_17 | 17 | /dev/gpiochip4 | GPIO/SPI/UART/I2C | > **注意**:Pin3和Pin5默认配置为I2C9接口,如需作为GPIO使用,请确保没有其他设备占用。 完整的引脚映射请参考:[40-Pin扩展](<../../使用指南/40-Pin扩展/40-Pin扩展.md>) # lgpio API参考 ## GPIO芯片操作 ```c // 打开GPIO芯片int lgGpiochipOpen(int chip_num);// 关闭GPIO芯片int lgGpiochipClose(int handle); ``` ## GPIO配置 ```c // 申请GPIO为输出模式int lgGpioClaimOutput(int handle, int flags, int gpio, int level);// 申请GPIO为输入模式int lgGpioClaimInput(int handle, int flags, int gpio);// 释放GPIOint lgGpioFree(int handle, int gpio); ``` ## GPIO读写 ```c // 读取GPIO电平int lgGpioRead(int handle, int gpio);// 写入GPIO电平int lgGpioWrite(int handle, int gpio, int level); ``` ## PWM控制 ```c // 输出PWM信号int lgTxPwm(int handle, int gpio, float freq, float duty, int offset, int cycles); ``` # 常见问题 ## 编译错误 **问题:找不到lgpio.h** ```plaintext fatal error: lgpio.h: No such file or directory ``` **解决方法:** 1. 确认lgpio库已安装 2. 检查头文件路径:*ls /usr/local/include/lgpio.h* 3. 如果在其他路径,编译时指定:*gcc -I/path/to/include ...* ## 运行时错误 **问题:Permission denied** **解决方法:** 使用 *sudo* 运行程序: ```bash sudo ./gpio_output 36 1 ``` **问题:找不到共享库** ```plaintext error while loading shared libraries: liblgpio.so ``` **解决方法:** ```bash # 更新动态链接库缓存sudo ldconfig # 或者设置LD_LIBRARY_PATHexport LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH ``` ## 引脚占用问题 如果遇到GPIO已被占用的错误,使用以下命令检查: ```bash # 查看GPIO状态 gpioinfo /dev/gpiochip4 | grep -E "(line 36|line 37|consumer)" ``` 如果引脚被占用,需要先释放或选择其他未占用的引脚。 # 参考资源 - [lgpio GitHub仓库]() - [lgpio官方文档]() - [40-Pin扩展](<../../使用指南/40-Pin扩展/40-Pin扩展.md>) - [Python GPIO开发](<../Python GPIO开发/Python GPIO开发.md>)